#include "share/Usrdef.h"
#include "core/globalvar.h"
#include "share/parameters.h"
#include "share/pulseseq.h"

double   	MIN_TIME;						//starting time
double   	MAX_TIME;						//finishing time
int			NTIME;
double 		MIN_FREQ;
double   	MAX_FREQ;						//maximum angular frequency
int			NFREQ;
double		NOISE_AMPLITUDE;
double		CORRELATION_TIME;
int 		NPATH;
int			N_INTERPOLATION;
int			SIM_SEED;
double		OMEGA_Z;
double		OMEGA_V;
int			GAUSS_INT_ORDER;
double		ABS_EPSLON;
double		GAUSS_INTERVAL;
char     	STR_SEQ_NAME[10];
int			PULSE_NUM;
int			SEQ_NAME;

double   	TIME_STEP;
double 		FREQ_STEP;
double		OMEGA_0;
int			CDD_ORDER;

char		PARA_CHAR[500];
char		OUTPUT_FILE[500];

char     VERSION_INFO[100];
char     EXEC[200];


char* itoa(int val, int base){

	static char buf[32] = {0};

	int i = 30;

	for(; val && i ; --i, val /= base)

		buf[i] = "0123456789abcdef"[val % base];

	return &buf[i+1];

}

void ParameterResolve(int argc, char ** argv)
{
    //version
    char ver[100], ver_str1[50], ver_str2[50], ver_str3[50];

    strcpy(ver, CODE_PATH);
    strcat(ver, "bin/Version.log");
    ifstream version(ver);
    if (!version) assert(0);

    version >> ver_str1 >> ver_str2 >> ver_str3;
    cout << "Src version:\t"	<< ver_str1 << " "<<  ver_str2 << " " << ver_str3 << endl;

    strcat(VERSION_INFO, ver_str2);
    strcat(VERSION_INFO, ver_str3);

    version.close();

    //parse parameters
    strcpy(EXEC, argv[0]);

    cout << "#######################################" << endl;
	cout << "Parameter Number: " << argc - 1 << endl;



	int paraFlag, is_default_config = 1, is_set_u = 0;

    optind = 1;
    while ((paraFlag = getopt (argc, argv, "g:S:E:k:Q:W:q:o:B:T:a:s:Z:V:D:X:p:n:")) != -1)
    {
        switch (paraFlag)
        {
        	case 'g':
				cout << "group name = " << optarg << endl ;
				strcat(PARA_CHAR, "_g");
				strcat(PARA_CHAR, optarg);
				break;
        	case 'S':
        		MIN_TIME = atof(optarg);
        		cout << "Start time = " << MIN_TIME << endl ;
        		strcat(PARA_CHAR, "_S");
        		strcat(PARA_CHAR, optarg);
        		break;
        	case 'E':
        		MAX_TIME = atof(optarg);
        		cout << "End time = " << MAX_TIME << endl ;
        		strcat(PARA_CHAR, "_E");
        		strcat(PARA_CHAR, optarg);
        		break;
        	case 'k':
        		NTIME = atoi(optarg);
        		cout << "Ntime = " << NTIME << endl ;
        		strcat(PARA_CHAR, "_k");
        		strcat(PARA_CHAR, optarg);
        		break;
        	case 'Q':
        		MIN_FREQ = atof(optarg);
        		cout << "MIN Freq = " << MIN_FREQ << endl ;
        		strcat(PARA_CHAR, "_Q");
        		strcat(PARA_CHAR, optarg);
        		break;
        	case 'W':
        		MAX_FREQ = atof(optarg);
        		cout << "Max. Freq = " << MAX_FREQ << endl ;
        		strcat(PARA_CHAR, "_W");
        		strcat(PARA_CHAR, optarg);
        		break;
        	case 'q':
        		NFREQ = atoi(optarg);
        		cout << "NFreq = " << NFREQ<< endl ;
        		strcat(PARA_CHAR, "_q");
        		strcat(PARA_CHAR, optarg);
        		break;
        	case 'o':
        		N_INTERPOLATION = atoi(optarg);
        		cout << "N_Interpolation = " << N_INTERPOLATION<< endl ;
        		strcat(PARA_CHAR, "_o");
        		strcat(PARA_CHAR, optarg);
        		break;
        	case 'B':
        		NOISE_AMPLITUDE = atof(optarg);
        		cout << "Noise amplitude = " << NOISE_AMPLITUDE << endl ;
        		strcat(PARA_CHAR, "_B");
        		strcat(PARA_CHAR, optarg);
        		break;
        	case 'T':
        		CORRELATION_TIME = atof(optarg);
        		cout << "Correlation time = " << CORRELATION_TIME << endl ;
        		strcat(PARA_CHAR, "_T");
        		strcat(PARA_CHAR, optarg);
        		break;
        	case 'a':
        		NPATH = atoi(optarg);
        		cout << "Npath = " << NPATH << endl ;
        		strcat(PARA_CHAR, "_a");
        		strcat(PARA_CHAR, optarg);
        		break;
        	case 's':
        		SIM_SEED = atoi(optarg);
        		cout << "seed = " << SIM_SEED<< endl ;
        		strcat(PARA_CHAR, "_s");
        		strcat(PARA_CHAR, optarg);
        		break;
        	case 'Z':
        		OMEGA_Z= atof(optarg);
        		cout << "Omega z = " << OMEGA_Z<< endl ;
        		strcat(PARA_CHAR, "_Z");
        		strcat(PARA_CHAR, optarg);
        		break;
        	case 'V':
        		OMEGA_V = atof(optarg);
        		cout << "Omega v = " << OMEGA_V << endl ;
        		strcat(PARA_CHAR, "_V");
        		strcat(PARA_CHAR, optarg);
        		break;
        	case 'D':
        		ABS_EPSLON = atof(optarg);
        		cout << "Abs eps = " << ABS_EPSLON << endl ;
        		strcat(PARA_CHAR, "_D");
        		strcat(PARA_CHAR, optarg);
        		break;
        	case 'X':
        		GAUSS_INTERVAL = atof(optarg);
        		cout << "Gauss Interval = " << GAUSS_INTERVAL << endl ;
        		strcat(PARA_CHAR, "_X");
        		strcat(PARA_CHAR, optarg);
        		break;
            case 'p':
            	strcpy(STR_SEQ_NAME, optarg);
            	strcat(PARA_CHAR,"_p");
            	strcat(PARA_CHAR, optarg);
            	break;
            case 'n':
            	PULSE_NUM = atoi(optarg);
            	strcat(PARA_CHAR,"_n");
            	strcat(PARA_CHAR, optarg);
            	break;

            case '?':
                if (isprint (optopt))
                    fprintf (stderr, "Unknown option `-%c'.\n", optopt);
                else
                    fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt);
                abort ();
            default:
                abort ();
        }
    }
    cout << "#######################################" << endl;

    strcpy(OUTPUT_FILE, "res_");
    strcat(OUTPUT_FILE, PARA_CHAR);
    strcat(OUTPUT_FILE, ".dat");

    //////////////////////////////////////////////////////////////////
    //determine the pulse sequence
    if (strcmp(STR_SEQ_NAME, "UDD") == 0) //parameter 1 == UDD
    {
    	SEQ_NAME = 1;
    }
    else if (strcmp(STR_SEQ_NAME, "PDD") == 0) //parameter 2 == PDD
    {
    	SEQ_NAME = 2;
    }
    else if (strcmp(STR_SEQ_NAME, "CDD") == 0) //parameter 3 == CDD
    {
    	SEQ_NAME = 3;
    }
    else
    {
    	SEQ_NAME = -1;
    	cout << "***** ERROR: unknown pulse sequence. *****" << endl;
    	assert(0);
    }
    //////////////////////////////////////////////////////////////////
    // Special treatment for CDD
    if (SEQ_NAME == 3)   //CDD
    {
    	CDD_ORDER = PULSE_NUM;
    	PULSE_NUM = get_CDD_pulse_num(CDD_ORDER);
    }

    TIME_STEP = ( MAX_TIME - MIN_TIME ) / NTIME;
    FREQ_STEP = ( MAX_FREQ - MIN_FREQ ) / NFREQ;
    OMEGA_0 = sqrt(OMEGA_V*OMEGA_V + OMEGA_Z*OMEGA_Z);
}
